package com.wltt.product.ahuthr.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.wltt.product.ahuthr.config.exception.BusinessException;
import com.wltt.product.ahuthr.enums.ImportTypeEnum;
import com.wltt.product.ahuthr.mapper.*;
import com.wltt.product.ahuthr.model.po.ImportRecordPO;
import com.wltt.product.ahuthr.model.po.SalaryPO;
import com.wltt.product.ahuthr.model.po.UserBasicPO;
import com.wltt.product.ahuthr.service.SalaryHouseFundService;
import com.wltt.product.ahuthr.service.SalaryLevelService;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SalaryLevelListener implements ReadListener<SalaryLevelData> {
    private SalaryLevelService salaryLevelService;
    private UserBasicMapper userBasicMapper;
    private SalaryMapper salaryMapper;
    private ImportRecordMapper importRecordMapper;
    private ImportRecordPO importRecordPO;

    private ExcelWriter excelWriter;
    private WriteSheet dataSheet;
    private WriteSheet failSheet;
    private File errorExcel;

    Date startDate;
    long dataCount = 0;
    long successCount = 0;
    long failCount = 0;

    public SalaryLevelListener(SalaryLevelService salaryLevelService,
                               UserBasicMapper userBasicMapper,
                               SalaryMapper salaryMapper,
                               SalaryLevelMapper salaryLevelMapper,
                               ImportRecordMapper importRecordMapper,
                               ImportRecordPO importRecordPO,
                               File errorExcel) {
        this.salaryLevelService = salaryLevelService;
        this.userBasicMapper = userBasicMapper;
        this.salaryMapper = salaryMapper;
        this.importRecordMapper = importRecordMapper;
        this.importRecordPO = importRecordPO;

        this.errorExcel = errorExcel;
        excelWriter = EasyExcel.write(errorExcel, SalaryLevelFailData.class).build();
        dataSheet = EasyExcel.writerSheet("importData").build();
        failSheet = EasyExcel.writerSheet("failData").build();
        startDate = new Date();
    }

    @Override
    public void invoke(SalaryLevelData data, AnalysisContext analysisContext) {
        try {
            dataCount++;
            // 先写入结果文件
            writeData(data);

            // 数据校验
            if (null == data.getJobNumber()) {
                writeFailData(data, "工号不能为空");
                return;
            }
            if (null == data.getPostTypeName()) {
                writeFailData(data, "工资系列不能为空");
                return;
            }
            Long postTypeId;
            try {
                postTypeId = Long.valueOf(data.getPostTypeName().substring(0, data.getPostTypeName().indexOf("-")));
            } catch (Exception e) {
                writeFailData(data, "工资系列格式错误");
                return;
            }

            if (null == data.getLevel()) {
                writeFailData(data, "薪级不能为空");
                return;
            }
            if (null == data.getLevelSalary()) {
                writeFailData(data, "薪级工资不能为空");
                return;
            }
            if (null == data.getSalary10()) {
                writeFailData(data, "工资百分之10不能为空");
                return;
            }

            UserBasicPO userBasicPO = userBasicMapper.queryByJobNumber(data.getJobNumber());
            if (null == userBasicPO) {
                writeFailData(data, "人员不存在");
                return;
            }
            SalaryPO salaryPO = salaryMapper.queryByUserId(userBasicPO.getId());
            if (null == salaryPO) {
                writeFailData(data, "人员未起薪");
                return;
            }

            // 更新数据库
            salaryLevelService.updateSalaryLevelSevel(salaryPO.getId(), postTypeId, data.getLevel(), data.getLevelSalary(), data.getSalary10());

            successCount++;
        } catch (BusinessException e) {
            writeFailData(data, e.getMessage());
        } catch (Exception e) {
            writeFailData(data, "系统错误，请手动调整");
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        try {
            excelWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        importRecordPO.setImportType(ImportTypeEnum.SALARY_LEVEL.getCode());
        importRecordPO.setImportCount(dataCount);
        importRecordPO.setImportSuccessCount(successCount);
        importRecordPO.setImportFailCount(failCount);
        importRecordPO.setImportResultFile(errorExcel.getName());
        importRecordPO.setImportStatus(200);
        importRecordMapper.updateById(importRecordPO);
    }

    private void writeData(SalaryLevelData data) {
        List<SalaryLevelData> excelData = new ArrayList<>();
        excelData.add(data);
        excelWriter.write(excelData, dataSheet);
    }

    private void writeFailData(SalaryLevelData data, String failReason) {
        failCount++;
        SalaryLevelFailData failData = new SalaryLevelFailData();
        failData.setNumber(data.getNumber());
        failData.setJobNumber(data.getJobNumber());
        failData.setPostTypeName(data.getPostTypeName());
        failData.setLevel(data.getLevel());
        failData.setLevelSalary(data.getLevelSalary());
        failData.setSalary10(data.getSalary10());
        failData.setFailReason(failReason);
        List<SalaryLevelFailData> excelData = new ArrayList<>();
        excelData.add(failData);
        excelWriter.write(excelData, failSheet);
    }
}
